<template>
  <div class="ad-template-brand">
    <template v-if="isOther">
      <!--优量汇 独立品牌图片-->
      <TemplateMedia v-if="brandImg" :ref="setBrandImgRef" :params="brandImg" />
      <!--713、716 独立品牌名称-->
      <TemplateText v-if="brandName" :ref="setBrandNameRef" :params="brandName" />
    </template>
    <!--传统下拉选择-->
    <x-form v-else :ref="setItemRef" v-model:model="formData" :rules="rules">
      <n-form-item :label="getProps.params.description || '品牌标识'" path="brand">
        <n-select v-model:value="formData.brand" :placeholder="`请选择一个${getProps.params.description}，与广告创意一起展示`"
          :options="brandList" value-field="_id" label-field="name" @update:value="onChange">
          <template #action>
            <div class="ad-template-brand-option" :disabled="true">
              <span>找不到{{ getProps.params.description }}？请</span><em style="color: #536fff; cursor: pointer"
                @click="showAddBrand">上传{{ getProps.params.description }}</em>
              <n-divider vertical />
              <em style="color: #536fff; cursor: pointer" @click="getBrandList">刷新</em>
            </div>
          </template>
        </n-select>
      </n-form-item>
    </x-form>
    <n-modal v-if="!isOther" v-model:show="dialogVisible" preset="card" :title="`上传${getProps.params.description}`"
      :style="{ width: '500px' }" @update:show="onClose">
      <div v-if="brandImg" class="ad-template-media">
        <div class="title">{{ brandImg.description }}</div>
        <div v-if="error" class="error">{{ errorMessage || `请上传${brandImg.description}` }}</div>
        <f-upload ref="uploadRef" class="f-ad-upload-1" :limit="1" :params="uploadParams" :default-upload="false"
          :show-file-list="false" :with-credentials="true" :isName="true" @before-upload="beforeUpload"
          @finish="onSuccess" @error="onError">
          <div v-if="isPercentage" class="percentage">
            <n-progress :stroke-width="16" :percentage="percentage" />
          </div>
          <!-- 预览-->
          <div v-else-if="fileUrl" class="preview-block">
            <div class="preview">
              <n-image :src="fileUrl" fit="contain" />
              <div class="preview-tips">
                <p>
                  <span>{{ imageSize }}</span>
                  <span>点击重新上传</span>
                </p>
              </div>
              <!--              <div class="tools-close" @click.stop="onClosePic">-->
              <!--                <x-icon class="iconfont icon-073" />-->
              <!--              </div>-->
            </div>
          </div>
          <!-- 转码等待-->
          <div v-else-if="isLoading" class="loading-block">
            <dl>
              <dd><i class="n-icon-loading" /></dd>
              <dt>图片智能截剪中...</dt>
            </dl>
          </div>
          <dl v-else class="f-upload-tips">
            <dt>{{ imageSize }}</dt>
            <dd>
              <p>点击上传图片</p>
              <p>{{ fileFormat.join('/').toUpperCase() }}，{{ bytesToSize(entity.file_size) }}</p>
            </dd>
          </dl>
        </f-upload>
      </div>
      <x-form ref="form" v-model:model="brandFormData" :rules="brandFormRules">
        <n-form-item label="品牌名称" path="brandNameInput">
          <n-input v-model:value="brandFormData.brandNameInput" />
        </n-form-item>
      </x-form>
      <template #footer class="dialog-footer">
        <n-space justify="end">
          <x-button @click="dialogVisible = false">取 消</x-button>
          <x-button :loading="loading" type="primary" @click="saveBrand">确 定</x-button>
        </n-space>
      </template>
    </n-modal>
  </div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router'
import { XForm, XButton, XIcon } from '@/components'
import TemplateText from '@/views/advertising/ads/create/components/step7/TemplateText.vue'
import TemplateMedia from '@/views/advertising/ads/create/components/step7/TemplateMedia.vue'
import FUpload from '@/views/advertising/ads/create/components/step7/FUpload.vue'
import { computed, onMounted, reactive, ref, nextTick, watch } from 'vue'
import { useStore } from '@/store'
import { bytesToSize } from '@/utils/index'
import { useMessage, NSpace, NProgress, NModal, NSelect, NFormItem, NImage, NInput, NDivider } from 'naive-ui'

const message = useMessage()
const route = useRoute()
const store = useStore()
const props = defineProps({
  params: {
    type: Object,
    default: () => ({})
  }
})
const getProps = reactive(props)

const isEdit = computed(() => {
  return store.state.intelligent.data.id
})
const siteSet = computed(() => {
  return store.state.intelligent.data.position.siteSet
})
const creative = computed(() => {
  return store.state.intelligent.data.creative
})
// 15 优量汇
const is15 = computed(() => {
  return siteSet.value === 'SITE_SET_MOBILE_UNION'
})
const is100 = computed(() => {
  return (
    siteSet.value.some((s) => s === 'SITE_SET_KANDIAN') || siteSet.value.some((s) => s === 'SITE_SET_QQ_MUSIC_GAME')
  )
})
const brandImg = computed(() => {
  return getProps.params.children.brand_img || getProps.params.children.corporate_img
})
const brandName = computed(() => {
  return getProps.params.children.brand_name || getProps.params.children.corporate_name
})
const brandKeys = computed(() => {
  return {
    img: brandImg.value ? brandImg.value.name : null,
    name: brandName.value ? brandName.value.name : null
  }
})
// 资源属性与规则
const entity = computed(() => {
  return brandImg.value ? getProps.params.children[brandKeys.value.img].restriction.image_restriction : {}
})
// 推荐尺寸
const imageSize = computed(() => {
  return `${entity.value.width}px X ${entity.value.height}px`
})
// 文件格式
const fileFormat = computed(() => {
  const type = {
    IMAGE_TYPE_JPG: '.jpg',
    IMAGE_TYPE_PNG: '.png'
  }
  return entity.value.file_format.map((item) => {
    return type[item]
  })
})
const isPercentage = computed(() => {
  return percentage.value > 0 && percentage.value < 100
})
const isLoading = computed(() => {
  return percentage.value === 100 && !fileUrl.value
})
const accountCode = computed(() => {
  return store.state.intelligent.data.accountCode
})
const uploadParams = computed(() => {
  return {
    action: '/api/engine/ad/brand/upload',
    accept: fileFormat.value.join(','),
    data: {
      accountCode: accountCode.value,
      width: entity.value.width, // 商标时使用
      height: entity.value.height, // 商标时使用
      name: brandFormData.value.brandNameInput
    },
    rules: {
      width: entity.value.width,
      height: entity.value.height,
      fileSize: entity.value.file_size
    }
  }
})
const isCorporate = ref(false)
const isOther = ref(false)
const rules = ref({
  brand: []
})
const formData = ref({
  brand: []
})
const fileName = ref(null)
const fileUrl = ref(null)
const loading = ref(false)
const error = ref(false)
const errorMessage = ref(null)
const percentage = ref(0)
const brandList = ref()
const dialogVisible = ref(false)
const uploadRef = ref()
const form = ref()
const brandFormData = ref({
  brandNameInput: ''
})
const brandFormRules = ref({
  brandNameInput: {
    type: 'string',
    required: true,
    message: '请输入品牌名称',
    trigger: ['blur', 'change']
  }
})
const itemRefs = {}
const setItemRef = (el: any) => {
  if (el) {
    const key = getProps.params.name
    itemRefs[key] = el
  }
}
const brandImgRefs = {}
const setBrandImgRef = (el: any) => {
  if (el) {
    const key = brandImg.value.name
    brandImgRefs[key] = el
  }
}
const brandNameRefs = {}
const setBrandNameRef = (el: any) => {
  if (el) {
    const key = brandName.value.name
    brandNameRefs[key] = el
  }
}
onMounted(() => {
  // 编辑状态下触发下面逻辑
  if (getProps.params.default) {
    formData.value.brand =
      getProps.params.default[brandKeys.value.name] + getProps.params.default[brandKeys.value.img]
  }
  if (!isOther.value) {
    initRules()
    getBrandList()
  }
})
function handleUploadMessage() {
  message.warning('请先填写品牌名称')
}
// 初始化校验规则
function initRules() {
  // 必填、可选
  if (getProps.params.required) {
    rules.value.brand.push({
      required: getProps.params.required,
      message: getProps.params.description || '不能为空',
      trigger: ['blur', 'change']
    })
  }
}
// 获取当前已有品牌列表
async function getBrandList() {
  const res = isCorporate.value
    ? await store.dispatch('intelligent/getAdsImageList', {
      accountCode: accountCode.value,
      width: entity.value.width,
      height: entity.value.height
    })
    : await store.dispatch('intelligent/getAdsBrandList', {
      accountCode: accountCode.value
    })
  if (res.data) {
    res.data.forEach((item) => {
      if (isCorporate.value) {
        item.name = item.corporateName
      }
      item._id = item.name + item.imageId
    })
    brandList.value = res.data
    // 如果已有选中值，但匹配不到列表数据，清除选中值
    if (formData.value.brand && !res.data.find((item) => item._id === formData.value.brand)) {
      formData.value.brand = ''
    }
  }
}
// 校验
function validate() {
  return new Promise(async (resolve, reject) => {
    if (isOther.value) {
      // [713, 716, 718] && is15
      const name = brandName.value ? await brandNameRefs[brandName.value.name].validate() : true
      const img = brandImg.value ? await brandImgRefs[brandImg.value.name].validate() : true
      if (name && img) {
        resolve(true)
      } else {
        resolve(false)
      }
    } else {
      itemRefs[getProps.params.name].validate((errors) => {
        if (!errors) {
          resolve({
            [getProps.params.name]: getProps.params.default
          })
        } else {
          message.warning(`请选择${getProps.params.description}`)
          resolve(false)
        }
      })
    }
  })
}
// 选择品牌
function onChange(val) {
  const current = brandList.value.find((item) => item._id === val)
  getProps.params.default = {
    [brandKeys.value.name]: current.name,
    [brandKeys.value.img]: String(current.imageId)
  }
  brandName.value.default = current.name
  brandImg.value.default = String(current.imageId)
  getProps.params.fileUrl = current.previewUrl
  // this.$set(getProps.params, 'fileUrl', current.previewUrl);
}
// 展示新建品牌弹出
function showAddBrand() {
  dialogVisible.value = true
  nextTick(() => {
    itemRefs[getProps.params.name].restoreValidation()
  })
  onClose()
}
function onClose() {
  fileUrl.value = null
  brandFormData.value.brandNameInput = null
}
// 确定新增的品牌数据
async function saveBrand() {
  if (!fileUrl.value || error.value) {
    error.value = true
    return message.warning(`请上传${brandImg.value.description}`)
  }
  await validateForm()
  // 创建新品牌标识
  nextTick(() => {
    // 执行上传
    loading.value = true
    uploadRef.value.submit()
  })
}
function validateForm() {
  return new Promise<void>((resolve, reject) => {
    form.value?.validate(async (errors: any) => {
      if (!errors) {
        try {
          resolve()
        } catch (e) {
          reject()
        }
      } else {
        reject()
        console.log('errors', errors)
      }
    })
  })
}
// 上传前
function beforeUpload(file: { status: string; file: Blob }) {
  return new Promise((resolve, reject) => {
    fileUrl.value = null
    uploadRef.value.clear()
    if (file.status === 'pending') {
      error.value = false
      const reader = new FileReader()
      reader.readAsDataURL(file.file)
      reader.onload = (evt) => {
        const replaceSrc = evt.target.result
        const imageObj = new Image()
        imageObj.src = replaceSrc
        imageObj.onload = () => {
          const { width, height } = imageObj
          if (
            width === entity.value.width &&
            height === entity.value.height &&
            file.file.size <= entity.value.file_size * 1024
          ) {
            fileUrl.value = replaceSrc
            error.value = false
            resolve(true)
          } else {
            uploadRef.value.clear()
            error.value = true
            errorMessage.value = `素材尺寸、大小不符合要求；请选择${entity.value.width}px X ${entity.value.height
              }px、≤${bytesToSize(entity.value.file_size)}的素材`
            reject(false)
          }
        }
      }
    } else {
      reject(false)
    }
  })
}
// 上传中
function onProgress(event) {
  const multiple = Math.pow(10, 2)
  percentage.value = Math.round(event.percent * multiple) / multiple
}
// 文件上传成功时的钩子
function onSuccess(res) {
  // 此处可能需要根据 response 的值，校验接口是否成功
  loading.value = false
  const data = res
  // 上传成功
  if (data) {
    // if (isCorporate.value) {
    //   data.name = data.corporateName
    // }
    const name = brandFormData.value.brandNameInput
    message.success(`${getProps.params.description}创建成功~`)
    // 重新加载列表
    getBrandList()
    // 选中当前新建的品牌标识
    formData.value.brand = name + data.imageId
    // 品牌对象，创建广告时提交的数据结构
    getProps.params.default = {
      [brandKeys.value.name]: name,
      // [brandKeys.value.img]: String(data.mediaId)
      [brandKeys.value.img]: String(data.imageId)
    }
    // 赋予子级值
    brandName.value.default = name
    // brandImg.value.default = String(data.mediaId)
    brandImg.value.default = String(data.imageId)
    // 文件预览地址
    getProps.params.fileUrl = data.previewUrl
    fileUrl.value = null
    brandFormData.value.brandNameInput = ''
    dialogVisible.value = false
  } else {
    message.error(res.msg || '上传出错，请校对是否符合上传要求')
    onClosePic()
  }
}
// 上传失败
function onError() {
  console.log('error')
  onClosePic()
}
// 清除
function onClosePic() {
  fileUrl.value = null
  loading.value = false
  if (getProps.params.default) {
    getProps.params.default = {
      [brandKeys.value.img]: null
    }
  }
}
defineExpose({
  validate
})
</script>

<style scoped lang="scss"></style>
